<?php
require_once dirname(__FILE__) . '/User.interface.php';
/**
 * @author Peter Gjøl
 *
 *
 * To be implementet.
 * Not yet done but you get the idea.
 *
 */
class WideFileUser
{
    private $_users;
    private $_groups;
    private $c_user = null;
    private $_changed = false;
    public  $validated = false;
    private static $_userpath;
    private static $_grouppath;

    public function __construct( $userId = "guest" ,  $password = null, $validated = false){
        WideFileUser::$_userpath = _SETTINGSPATH_."/users/";
        WideFileUser::$_grouppath = _SETTINGSPATH_."/groups/";

        if(empty($userId)){
            $userId = "guest";
            $validated = true;
        }
        if(!empty($userId) && (!empty($password)||$validated)){

            if(!empty($userId) && file_exists(WideFileUser::$_userpath.md5($userId).".ser")){
                $this->_users[$userId] = unserialize(file_get_contents(WideFileUser::$_userpath.md5($userId).".ser"));
                if($validated || $this->_users[$userId]["password"] === sha1($password)){
                    $this->c_user = $userId;
                    $this->validated =true;
                }
            } else {$this->validated = false;}
        }

        if($this->validated){
            $group = WideFileUser::$_grouppath.md5($this->_users[$this->c_user]['group_id']).".ser";
            if(file_exists($group)) {
                $this->_users[$this->c_user]['permissions'] = unserialize(file_get_contents($group));

            } else {
                $this->_users[$this->c_user]['permissions'] = unserialize(file_get_contents("$WideFileUser::$_grouppath".md5('guest').".ser"));
                $this->_users[$this->c_user]['group_id'] = 'guest';
            }
            $this->_groups[$this->_users[$this->c_user]['group_id']] = $this->_users[$this->c_user]['permissions'];
            return true;
        }

        return false;
    }
    //################## LEGACY #######################
    public function username() // DEPRECADET; use getUserName() instead
    {
        if(!empty($this->c_user) || $this->c_user != "guest") return $this->c_user;
    }
    public function userlist() // DEPRECADET; use getUserList() instead
    {
      return $this->getUserList();
    }
    public function usergroups() // DEPRECADET; use getGroupList() instead
    {
        return $this->getGroupList();
    }
    public function permissions($data=null) // DEPRECADET; either update gruop-perms, or set other group for user
    {
        $usr = &$this->_users[$this->c_user];
        if ($data)
            $usr['permissions'] = $data;
        return $usr['permissions'];
    }
    public function permissions_update() // DEPRECATED; handled automatically on __destruct
    {
        $this->getUserInfo();
    }

    //################# END LEGACY ####################
    public function getCurrentUser(){
        return $this->c_user;
    }
    public function getUserInfo( $id = null){
        if(empty($id) && !empty($this->c_user)){
            $id = $this->c_user;
        }
        if(empty($id)) return false;
        return $this->_users[$id];

    }

    public function setUserInfo( $id = null, $name = null ,  $groupID = null,  $password = null )
    {
        $tmpuser = null;
        if($id!=null && isset($this->_users[$id])){
            $tmpuser = &$this->_users[$id];
         } elseif($name!=null){
            foreach($this->_users as &$u){
                if($u['name']==$name){
                    $tmpuser = &$u;
                    break;
                }
            }
        } else {
            return false;
        }
        $tmpuser['changed'] = true;
        if($password) $password = $this->_encodePassword($password);
        if(!$tmpuser) return false;
        $tmpuser['name'] = $name != null ? $name : $tmpuser['name'];
        $tmpuser['permissions']['id'] = $groupID != null ? $groupID : $tmpuser['permissions']['id'];
        $tmpuser['password'] = $password != null ? $password : $tmpuser['password'];
        $this->_changed = true;
        $this->_updateUserArrays();
        return true;
    }

    public function createUser($id, $name , $groupID , $password )
    {
        if(!$name || $this->_users[$id]) return false;
        $this->_users[$id] = array("deleteable"=>true);
        return $this->setUserInfo($id, $name, $groupID, $password);
    }

    public function deleteUser( $id)
    {
        unset($this->_users[$id]);
        unlink(WideFileUser::$_userpath.md5($id).".ser");
        return true;
    }

    public function setUserPassword( $password,  $id = null)
    {
        if($id!=null){
            return $this->setUserInfo($id, null, null, $password);
        } elseif(!empty($this->c_user)){
            return $this->setUserInfo($this->c_user, null, null, $password);
        } else {
            return false;
        }

    }

    public function setUserName( $name,  $id = null)
    {
        if($id!=null){
            return $this->setUserInfo($id, $name);
        } elseif(!empty($this->c_user)){
            return $this->setUserInfo($this->c_user, $name);
        } else {
            return false;
        }
    }

    public function setUserGroup( $groupID,  $id = null)
    {
        if($id!=null){
            return $this->setUserInfo($id, null, $groupID);
        } elseif(!empty($this->c_user)){
            return $this->setUserInfo($this->c_user, null,$groupID);
        } else {
            return false;
        }
    }

    public function getUserList( $groupID = null)
    {
        if ($handle = opendir(WideFileUser::$_userpath)) {
            while (false !== ($file = readdir($handle))) {
                if ($file != "." && $file != "..") {
                    $tmp = unserialize(file_get_contents(WideFileUser::$_userpath.$file));
                    if(!$this->_users[$tmp['id']])$this->_users[$tmp['id']] = $tmp;
                }
            }
            closedir($handle);
        }
        return $this->_users;
    }

    public function getGroupList()
    {
        if ($handle = opendir(WideFileUser::$_grouppath)) {
            while (false !== ($file = readdir($handle))) {
                if ($file != "." && $file != "..") {
                    $tmp = unserialize(file_get_contents(WideFileUser::$_grouppath.$file));
                    if(!$this->_groups[$tmp['id']])$this->_groups[$tmp['id']] = $tmp;
                }
            }
            closedir($handle);
        }
        return $this->_groups;
    }

    public function setGroupPerms( $groupID, array $perms)
    {
        $this->getGroupList();
        if(array_key_exists($groupID,$this->_groups)){
            $this->_groups[$groupID] = $perms;
            $this->_groups[$groupID]['id'] = $groupID;
            $this->_changed = true;
            $this->_groups[$groupID]['changed'] = true;
            $this->_updateUserArrays();
            return true;
        } else {
            return false;
        }

    }

    public function createGroup( $name, array $perms)
    {
         if(!array_key_exists($name,$this->_groups)){
             $this->_groups[$name] = $perms;
             $this->_groups[$name]["id"] = $name;
             $this->_changed=true;
             $this->_groups[$name]['changed'] = true;
            return true;
         } else {
             return false;
         }
    }

    public function deleteGroup( $id)
    {
        unset($this->_groups[$id]);
        unlink(WideFileUser::$_grouppath.md5($id).".ser");
        $this->_updateUserArrays();
    }
    private function _updateUserArrays(){

        if(!empty($this->_users))foreach($this->_users as &$u){
            if(!array_key_exists($u['group_id'], $this->_groups) && !file_exists(WideFileUser::$_grouppath.md5($u['group_id']).".ser")){
                $u['group_id'] = 'guest';
            }
            if(array_key_exists($u['group_id'], $this->_groups)){
                $u['permissions']=$this->_groups[$u['group_id']];
            } elseif(file_exists(WideFileUser::$_grouppath.md5($u['group_id']).".ser")){
                $u['permissions']=unserialize(file_get_contents(WideFileUser::$_grouppath.md5($u['group_id']).".ser"));
                $u['permissions']['id'] = $u['group_id'];
                $this->_groups[$u['group_id']] = $u['permissions'];
            }
        }
    }
    private function _encodePassword($password){
        return sha1($password);
    }
    public function __destruct(){
        if($this->_changed){
            $this->_updateUserArrays();
            if(!empty($this->_users))foreach($this->_users as $k => &$u){
                if($u['changed']){
                    unset($u['changed']);
                    $u['id'] = $k;
                    if(!$u['group_id']) $u['group_id'] = $u['permissions']['id'];
                    file_put_contents(WideFileUser::$_userpath.md5($k).".ser", serialize($u));
                }
            }
            
            if(!empty($this->_groups)) foreach($this->_groups as &$u){
                if($u['changed']){
                    unset($u['changed']);
                    file_put_contents(WideFileUser::$_grouppath.md5($u['id']).".ser", serialize($u));
                }
            }
        }
    }
}

?>
